home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxlibs / vatpm051 / example.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  34.3 KB  |  1,193 lines

  1.  
  2. /**************************************************************************
  3.   EXAMPLE.C
  4.  
  5.   Written by:  Eric Jorgensen (April, 1995)
  6.  
  7.   This code was written using Turbo C.  It is intended to demonstrate the
  8.   use of Varmint's Audio Tools and to provide a example code for program
  9.   who wish to use VAT.
  10.  
  11.               This code is FREEWARE
  12.  
  13.   You are free to distribute without any restrictions as long as you
  14.   charge no fee.
  15.  
  16.  
  17. **************************************************************************/
  18.  
  19.  
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <conio.h>
  23. #include <dos.h>
  24. #include <io.h>
  25. //#include <alloc.h>
  26. #include "sound.h"
  27. #include <math.h>
  28. #include <time.h>
  29. #include "graph.h"
  30.  
  31. #define getbit(x,y)  ((x>>y) & 0x01)
  32. #define setbit(x,y) x = x & (0x01<<y)
  33. #define togbit(x,y) x = x ^ (0x01<<y)
  34.  
  35.                   // function prototypes
  36. void fmdemo(void);
  37. void mididemo(void);
  38. void sb_intro(void);
  39. void dspdemo(void);
  40. void moddemo(void);
  41. void vsyncdemo(void);
  42. void introtext(void);
  43. void diagnostics(void);
  44. void debugoptions(void);
  45. void print_num(float i);
  46.  
  47.  
  48. //-------------------------- DATA and Globals --------------------
  49.  
  50.                   // Instrument data
  51. char    inst[9][11] =
  52.   {
  53.     { 0x03,0x01,0x00,0x00,0xF3,0xE4,0x64,0x35,0x00,0x01,0x00},  // Harpsichord
  54.     { 0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x06,0x03,0x00},  // intro voice
  55.     { 0x02,0x06,0x94,0x0A,0x80,0x80,0x00,0x00,0x00,0x00,0x00},  // intro voice
  56.     { 0x00,0x04,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00},
  57.     { 0x01,0x01,0x40,0x40,0x80,0x80,0x00,0x00,0x01,0x00,0x00},
  58.     { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01},
  59.     { 0xA5,0xB1,0xD2,0x80,0x81,0xF1,0x03,0x05,0x00,0x00,0x02},
  60.     { 0x72,0x62,0x1C,0x05,0x51,0x52,0x03,0x13,0x00,0x00,0x0E},
  61.     { 0x11,0x01,0x8A,0x40,0xF1,0xF1,0x11,0xB3,0x00,0x00,0x06}};
  62.  
  63. int vints[8] = {1,2,1,2,1,2,1,2}; // voice defs for introduction
  64.                   // Start/end frequencies for intro
  65. WORD startfreq[8] = {0xa000,0x6000,0xa000,0x2000,0x1000,0x9000,0xa000,0x6000};
  66. WORD endfreq[8] =   {0x0800,0x2800,0x4800,0x6800,0x8800,0xa800,0xc800,0xe800};
  67.  
  68. char *regname[11] = {             // FM register name list
  69.   "Amp mod/ vib/ eg type/ keyscale/ multiple 1",
  70.   "Amp mod/ vib/ eg type/ keyscale/ multiple 2",
  71.   "Key scale level / oper out level 1",
  72.   "Key scale level / oper out level 2",
  73.   "attack/decay rate 1",
  74.   "attack/decay rate 2",
  75.   "sustain level / release rate 1",
  76.   "sustain level / release rate 2",
  77.   "Feedback / Algorythm (oper 1&2)",
  78.   "Wave Form  Select (oper 1)",
  79.   "Wave Form  Select (oper 1)"
  80.   };
  81.  
  82. char *effect_primary[] = {        // MOD command names
  83.   "Arpeggio",
  84.   "PortaM up",
  85.   "PortaM down",
  86.   "Porta NOTE",
  87.   "Vibrato",
  88.   "porta+vol",
  89.   "Vib+vol",
  90.   "Tremolo",
  91.   "UNUSED",
  92.   "Set offset",
  93.   "Vol slide",
  94.   "Postn Jmp",
  95.   "Set Volume",
  96.   "Pat Break",
  97.   "special14",
  98.   "Set Speed"};
  99. char *effect_secondary[] = {
  100.   "Filter T/F",
  101.   "Finesld up",
  102.   "Finesld dn",
  103.   "Gliss T/F",
  104.   "Vibr WF",
  105.   "Finetune WF",
  106.   "Loop Pattrn",
  107.   "Tremolo WF",
  108.   "UNUSED",
  109.   "Retrigger",
  110.   "FineVolS up",
  111.   "FineVolS Dn",
  112.   "Cut Sample",
  113.   "Delay Sampl",
  114.   "Delay Pttrn",
  115.   "Invert Loop"};
  116.                       // Patchmap to work on really
  117.                       // lame MIDI ouput devices.
  118. BYTE mypatchmap[16] = {0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2};
  119.  
  120. char hexchar[16] = {"0123456789ABCDEF"};  //  hexidecimal character list
  121.  
  122. SAMPLE *sound1,*sound2,*aha;
  123. unsigned long int l1=1,l2=1,laha=1;
  124. FILE *diagoutput= NULL;
  125. int mpu_checked = FALSE;
  126.  
  127. /**************************************************************************
  128.   void main()
  129.  
  130.   DESCRIPTION:   Handles the main menu and sets things up
  131.  
  132. **************************************************************************/
  133. void main(int argc,char *argv[])
  134. {
  135.   int i= 0;
  136.   char r = 0,twirl[6]  = "|/-\\";
  137.  
  138. //  _setvideomode(_VRES16COLOR);
  139.  
  140.   if(argc>1) debugoptions();
  141.  
  142.   introtext();
  143.   diagnostics();
  144.  
  145.   if(diagoutput) {
  146.     fprintf(diagoutput,"DMA_bufferlen: %u\n",dma_bufferlen);
  147.     fprintf(diagoutput,"Sample Rate: %u\n",sample_rate);
  148.     fflush(diagoutput);
  149.   }
  150.  
  151.   if(SB_Setup()) {
  152.  
  153.     if(diagoutput) {
  154.       fprintf(diagoutput,"Post SB_setup settings: I:%d D:%d A:%X P:%X T:%d\n",intnr,dma_ch,io_addr,midi_port,card_id);
  155.       fprintf(diagoutput,"DSP Version: %u.%u\n",dsp_vers>>8,dsp_vers&0xff);
  156.       fflush(diagoutput);
  157.     }
  158.  
  159.     Go_Varmint();                            // Install  Varmint's tools
  160.     if(diagoutput) {
  161.       fprintf(diagoutput,"Got past Go_Varmint.\n");
  162.       fflush(diagoutput);
  163.     }
  164.  
  165.     sound1 = loadwave("doink.wav",&l1);     // Load up our sound effects
  166.     sound2 = loadwave("wooeep.wav",&l2);
  167.     aha = loadwave("aha.wav",&laha);
  168.     if(!sound1 || !sound2 || !aha) {
  169.       printf("ERROR loading sounds:  (%d,%d)\n",sound1,sound2);
  170.       exit(0);
  171.     }
  172.  
  173.     if(diagoutput) {
  174.       fprintf(diagoutput,"Got past loadwave.\n");
  175.       fflush(diagoutput);
  176.     }
  177.  
  178.     sb_intro();                              // Get their attention
  179.  
  180.     if(diagoutput) {
  181.       fprintf(diagoutput,"Got past sb_intro.\n");
  182.       fflush(diagoutput);
  183.       fclose(diagoutput);
  184.     }
  185.  
  186.     while(kbhit()) getch();
  187.     while(r != 'Q') {                       // Main input loop
  188.  
  189.       _clearscreen(_GCLEARSCREEN);             // CLear screen and draw menu
  190.       _settextcolor(8);//DARKGRAY);
  191.       //cprintf("far core left %lu",farcoreleft());
  192.       _settextcolor(7);
  193.       //textcolor(WHITE);
  194.       _settextposition(8,20);
  195. //      _settextposition(20,8);
  196.       _outtext("Demonstration:  Varmint's Audio Tools\n\n");
  197.       _settextcolor(14);
  198. //      textcolor(YELLOW);
  199.       _settextposition(10,30);
  200.       _outtext("1) FM voice");
  201.       _settextposition(11,30);
  202.       _outtext("2) MIDI");
  203.       _settextposition(12,30);
  204.       _outtext("3) Sounds");
  205.       _settextposition(13,30);
  206.       _outtext("4) MOD");
  207.       _settextposition(14,30);
  208. //      _outtext("5) VSYNC");
  209. //      _settextposition(20,30);
  210.       _outtext("Q) quit");
  211.  
  212.       while(!kbhit()) {                     // Draw a twirling thing while
  213.                         // we wait for a keypress.
  214.     _settextposition(16,35);
  215.     _outtext(" ");
  216.     cprintf("%c",twirl[++i%4]);
  217.     _settextposition(14,30);
  218.     msdelay(50);
  219.       }
  220.       r = toupper(getch());                 // grab some input
  221.  
  222.       if(r == '1') fmdemo();                // Do something with it
  223.       else if(r == '2') {
  224.     mididemo();
  225.       }
  226.       else if(r == '3') {
  227.     dspdemo();
  228.       }
  229.       else if(r == '4') {
  230.     moddemo();
  231.       }
  232. //      else if(r == '5') {
  233. //    vsyncdemo();
  234. //      }
  235.     }
  236.     Dropdead_Varmint();                     // Release Varmint's interrupt
  237.   }
  238.   else {
  239.     printf("SB_Setup returned this error: %s \n",errname[sberr]);
  240.     if(diagoutput) {
  241.       fprintf(diagoutput,"Failed SB_setup.\n");
  242.       fprintf(diagoutput,"SB_Setup returned this error: %s \n",errname[sberr]);
  243.     }
  244.   }
  245.  
  246. }
  247.  
  248.  
  249. /**************************************************************************
  250.   void vsyncdemo(void)
  251.  
  252.   DESCRIPTION: The demonstrates the use of VarmintVSync() for animation
  253.  
  254. **************************************************************************/
  255. void vsyncdemo(void)
  256. {
  257.   int x=5;
  258.   char *drawme = {"HONIG"};
  259.   char r=0;
  260.  
  261.   _clearscreen(_GCLEARSCREEN);
  262.  
  263.   vsync_toolong = 4;                // This is the number of varmint ticks
  264.                     // that can happen between vertical
  265.                     // retraces.  (Assuming that the
  266.                     // Monitor is refreshed at aroun 65 hz)
  267.  
  268.                     // Display intro text.
  269.   _settextposition(2,16);
  270.   _outtext("VAT's mixing kernel can interfere with ordinary functions that\n");
  271.   _outtext("monitor the vertical retrace bit, causing `jerky' animation.\n");
  272.   _outtext("With sync checking off, the animation above will jerk badly\n");
  273.   _outtext("when you play sounds.  (Make sure any background MOD music is\n");
  274.   _outtext("off, or you will not be able to see the difference.)\n\n");
  275.   _outtext("Press 1,2, or 3 to play sounds.\n");
  276.   _outtext("Press <space> to toggle sync checking, 'Q' to quit");
  277.  
  278.   _settextposition(60,23);                    // Display status of sync_on
  279.   _settextcolor(14);
  280. //  textcolor(YELLOW);
  281.   if(sync_on) _outtext("SYNC ON  ");
  282.   else _outtext("SYNC OFF ");
  283.  
  284.   while(toupper(r) != 'Q') {        // Input/animation loop
  285.     if(kbhit()) {                   // Key stroke waiting?
  286.       r = getch();
  287.       if(r == ' ') {                // toggle sync checking
  288.     sync_on ^= TRUE;
  289.     _settextposition(23,60);
  290.     if(sync_on) _outtext("SYNC ON  ");
  291.     else _outtext("SYNC OFF ");
  292.       }                             // Play sounds
  293.       else if(r == '1') playsound(sound1,l1);
  294.       else if(r == '2') playsound(sound2,l2);
  295.       else if(r == '3') playsound(aha,laha);
  296.     }
  297.  
  298.                     // Animate a little bit of text
  299.     _settextposition(4,x);
  300.     printf("     ");
  301.  
  302.     x++;
  303.     if(x>74) x= 1;
  304.  
  305.     _settextposition(4,x);
  306.     printf("%s",drawme);
  307.  
  308.     VarmintVSync();                 // Wait for a retrace to finish
  309.  
  310.   }
  311. }
  312.  
  313.  
  314. /**************************************************************************
  315.   moddemo(void)
  316.  
  317.   DESCRIPTION: Demo for playing MOD files
  318.  
  319. **************************************************************************/
  320. void moddemo(void)
  321. {
  322.   char twirl[6]  = "|/-\\";
  323.   char str[80];
  324.  
  325.   int i,playme = 0;
  326.   int k;
  327.   char r=0;
  328.   static MOD *mymod = NULL;
  329.   DWORD count=0,total=0;
  330.   double oh;
  331.  
  332.   _clearscreen(_GCLEARSCREEN);                             // Clear the screen
  333.  
  334.   if(!mymod) {                          // Load the mod on first entry
  335.     mymod = loadmod("noname.mod");
  336.     if(!mymod) {
  337.       _outtext("Unable to load MOD file: noname.mod");
  338.       msdelay(2000);
  339.       return;
  340.     }
  341.     mod_data = mymod;                   // Set initial mod parameters
  342.     mod_reset = TRUE;
  343.   }
  344.  
  345.   DSP_overhead = 1;                     // Turn on overhead checking
  346.   _settextcolor(5);
  347.  // textcolor(MAGENTA);
  348.  
  349.   _settextposition(2,4);
  350.   _outtext("MOD demo menu");                 // Draw the menu
  351.   _settextcolor(3);
  352. //  textcolor(CYAN);
  353.   _settextposition(4,4);
  354.   _outtext("V,v     - Change music volume");
  355.   _settextposition(5,4);
  356.   _outtext("T,t     - Change music tempo");
  357.   _settextposition(6,4);
  358.   _outtext("M       - Music On/off toggle");
  359.   _settextposition(7,4);
  360.   _outtext("R       - Reset MOD");
  361.   _settextposition(8,4);
  362.   _outtext("1-4     - Toggle Channels on/off");
  363.   _settextposition(9,4);
  364.   _outtext("S       - Select Current sample");
  365.   _settextposition(10,4);
  366.   _outtext("<Space> - Play Current sample");
  367.   _settextposition(12,4);
  368.   _outtext("Q       - Quit");
  369.  
  370.   _settextposition(16,2);
  371.   _outtext("MOD Title: ");
  372.   _outtext(mymod->title);
  373. //  printf("MOD Title: %s ",mymod->title);
  374.  
  375.  
  376.   while(toupper(r) != 'Q') {            // Input Loop
  377.  
  378.     if(kbhit()) {                       // Keyboard have input?
  379.     _settextposition(16,35);
  380.     _outtext(" ");
  381.     _outtext((char*)twirl[++i%4]);
  382. //    cprintf("%c",twirl[++i%4]);
  383.  
  384.       r = getch();                                 // Grab the key
  385.       if(r == 'm')
  386. // This is a band aid fix for a bug with the MOD funciton
  387.     if(mod_on==FALSE)
  388.        {
  389.        mod_reset=TRUE;
  390.        mod_on=TRUE;
  391.        }
  392.     else
  393.        mod_on ^= TRUE;                 // Mod on/off
  394.       else if(r == 'V') {                          // Volume louder
  395.     mod_volume--;
  396.     if(mod_volume < 1) mod_volume = 1;
  397.       }
  398.       else if(r == 'v') {                          // Volume softer
  399.     mod_volume++;
  400.     if(mod_volume > 16) mod_volume = 16;
  401.       }
  402.       else if(r == 'T') {                          // Tempo faster
  403.     mod_bytespertick-=10;
  404.     if(mod_bytespertick < dma_bufferlen) mod_bytespertick = dma_bufferlen;
  405.       }
  406.       else if(r == 't') {                          // Tempo slower
  407.     mod_bytespertick+=10;
  408.     if(mod_bytespertick > 10000) mod_bytespertick = 10000;
  409.       }
  410.       else if(r == 'r') mod_reset = TRUE;          // Mod reset
  411.       else if(r == '1') channel_select[0] ^= 1;    // Turn channels on/off
  412.       else if(r == '2') channel_select[1] ^= 1;
  413.       else if(r == '3') channel_select[2] ^= 1;
  414.       else if(r == '4') channel_select[3] ^= 1;
  415.       else if(r == 's') {                          // Cycle through samples
  416.     playme++;
  417.     while(!mymod->sdata[playme]) {
  418.       playme++;
  419.       if(playme>31) playme = 0;
  420.     }
  421.       }                                            // Play current sample
  422.       else if(r == ' ') playsound(mymod->sdata[playme],mymod->slength[playme]);
  423.     }
  424.  
  425.     k = vclock;
  426.     while(k == vclock)
  427.  
  428.     for(i = 0; i < 4; i++) {
  429.  
  430.                       // Darken unselected channels
  431.       if(channel_select[i]) _settextcolor(14);
  432.       else _settextcolor(6);
  433.  
  434.       _settextposition(18+i,2);                    // Print the label
  435. //      cprintf("CHANNEL%d:",i+1);
  436.       _outtext("CHANNEL");
  437.       print_num((i+1));
  438.       _outtext(":");
  439.  
  440.       _settextposition(18+i,16);                   // Print sample number
  441.       if(chan[i].position <= chan[i].end) {
  442.     print_num(chan[i].sample_number);
  443. //    cprintf("%d",chan[i].sample_number);
  444.       }
  445.       else _outtext("   ");
  446.  
  447.       _settextposition(18+i,22);
  448.       if(chan[i].position <= chan[i].end) {
  449.     if(chan[i].effect != 14)
  450. //    cprintf("%s       ",effect_primary[chan[i].effect]);
  451.     {
  452.     _outtext(effect_primary[chan[i].effect]);
  453.     _outtext("       ");
  454.     }
  455.     else
  456. //     cprintf("%s (E)      ",effect_secondary[chan[i].x]);
  457.     {
  458.      _outtext(effect_secondary[chan[i].x]);
  459.      _outtext(" (E)     ");
  460.      }
  461.       }
  462.       else _outtext("                  ");
  463.  
  464.       _settextposition(18+i,42);
  465.       print_num(chan[i].period);
  466. //      cprintf("%d",chan[i].period);
  467.  
  468.       _settextposition(18+i,52);
  469.       print_num(chan[i].volume);
  470. //      cprintf("%d",chan[i].volume);
  471.     }
  472.  
  473.     _settextposition(4,40);                         // SHow current volume
  474. //    printf("VOLUME BYTE: %d  ",mod_volume);
  475.     _outtext("VOLUME BYTE: ");
  476.     print_num(mod_volume);
  477.  
  478.     _settextposition(5,40);                         // Show the tempo
  479. //    printf("TEMPO: %d  ",mod_bytespertick);
  480.     _outtext("TEMPO: ");
  481.     print_num(mod_bytespertick);
  482.  
  483.     _settextposition(6,40);                         // Show playing status
  484.     if(mod_on) _outtext("MOD on  ");
  485.     else _outtext("MOD off   ");
  486.  
  487.     _settextposition(7,40);                         // Print channel name/command info
  488.     _outtext("Tick: ");
  489.     print_num(mod_currenttick);
  490.     _outtext(" Table position: ");
  491.     print_num(mod_tablepos);
  492. //    printf("Tick: %d Table position: %d  ",mod_currenttick,mod_tablepos);
  493.  
  494.     _settextposition(10,40);
  495. //    printf("Current sample: %d (%s)          ",playme+1,mymod->sample_name[playme]);
  496.     _outtext("Current sample: ");
  497.     print_num(playme+1);
  498.     _outtext("(");
  499.     _outtext(mymod->sample_name[playme]);
  500.     _outtext(")           ");
  501.     count++;
  502.     total+=DSP_overhead;
  503.     if(count == 20) {
  504.       oh = (total * 0.9218)/(count * dma_bufferlen) * sample_rate/11000.0;
  505.       _settextposition(23,4);
  506.       sprintf(str,"CPU Overhead: %.2lf%% ",oh);
  507.       _outtext(str);
  508.       total = 0;
  509.       count = 0;
  510.     }
  511.   }
  512.  
  513. }
  514.  
  515. void print_num(float i)
  516. {
  517. char *str;
  518. double num;
  519. int dec, sign, ndig = 1;
  520.  
  521. /* a regular number */
  522. str = fcvt(i, ndig, &dec, &sign);
  523. _outtext(str);
  524. }
  525.  
  526. /**************************************************************************
  527.   void dspdemo(void)
  528.  
  529.   DESCRIPTION:  Plays sound effects with Varmint's Audio Tools
  530.  
  531. **************************************************************************/
  532. void dspdemo(void)
  533. {
  534.   char r = 0;
  535.   DWORD tot = 0,num = 0,vc;
  536.   double oh;
  537.   char *str;
  538.  
  539.   int dec, sign, ndig = 5;
  540.  
  541.  
  542.   DSP_overhead = 1;                           // turn on overhead checking
  543.  
  544.   _clearscreen(_GCLEARSCREEN);                                   // Clear screen and draw a menu
  545.   _settextcolor(2);
  546. //  textcolor(GREEN);
  547.   _settextposition(8,25);
  548.   _outtext("Sound effects demo menu");
  549.   _settextcolor(14);
  550. //  textcolor(YELLOW);
  551.   _settextposition(10,25);
  552.   _outtext("1,2,3 - Play a sound effect");
  553.   _settextposition(11,25);
  554.   _outtext("Q     - Quit");
  555.  
  556.   _settextposition(1,1);
  557.   _outtext("CPU OVERHEAD: \nSAMPLES IN QUEUE: ");
  558.   while(toupper(r) != 'Q') {         // input loop
  559.     while(!kbhit()) {                // Wait for keystroke
  560.       vc = vclock;
  561. //      while(vc == vclock);           // wait for the interrupt
  562.  
  563.       tot+= DSP_overhead;            // take an average every 40 interrupts
  564.       num++;
  565.       if(num == 40) {
  566.     oh = (tot * 0.9218)/(num * dma_bufferlen)*sample_rate/11000;
  567.  
  568. //      str = fcvt(oh, ndig, &dec, &sign);
  569.     _settextposition(1,15);
  570. //    _outtext(str);
  571.     print_num(oh);
  572. //    printf("%2.2lf%%  ",oh); // Show overhead
  573.     _settextposition(2,19);
  574.     str = fcvt(sounds_in_queue, 1, &dec, &sign);
  575.  
  576. //    printf("%d  \n",sounds_in_queue);       // Show # sounds playing
  577.     _outtext(str);
  578.     _outtext("   ");
  579. //    print_num(sounds_in_queue);
  580.     num = 0;
  581.     tot = 0;
  582.       }
  583.     }
  584.     r = getch();                      // Get keystroke and act accordingly
  585.     if(r == '1') playsound(sound1,l1);
  586.     else if(r == '2') playsound(sound2,l2);
  587.     else if(r == '3') playsound(aha,laha);
  588.   }
  589. }
  590.  
  591. /**************************************************************************
  592.   void sb_intro(void)
  593.  
  594.   DESCRIPTION:  Cool introduction sith sound blaster music and sounds
  595.  
  596. **************************************************************************/
  597. void sb_intro(void)
  598. {
  599.   int i,j;
  600.   double fr;
  601.   WORD f;
  602.  
  603.   _clearscreen(_GCLEARSCREEN);
  604.   _settextposition(1,1);
  605.   printf("Varmint's Audio Tools  (Version: %s)",VAT_VERSION);
  606.   msdelay(500);
  607.  
  608.   // Cool introduction
  609. //  while(kbhit());
  610.  
  611.   FM_Reset();
  612.  
  613.   for(i = 0; i < 2; i++) {
  614.     playsound(aha,laha);              // Digital intro speach
  615.     msdelay(15);
  616.   }
  617.  
  618.   for(i = 0; i < 8; i++) {             // initialize music voices
  619.     FM_SetVoice(i,inst[vints[i]]);
  620.     FM_SetFreq(i,startfreq[i]);
  621.     FM_SetVol(i,0x00);
  622.     FM_KeyOn(i);
  623.   }
  624.   for(i = 0; i < 1000; i+= 1) {       // morph a big chord
  625.     fr = i/1000.0;
  626.     for(j = 0; j < 8; j++) {
  627.       _settextposition(10,j*10+1);
  628.       f = startfreq[j]+((double)endfreq[j]-(double)startfreq[j]) * fr;
  629.       cprintf("%X  ",f);
  630.       FM_SetFreq(j,f);
  631.       FM_SetVol(j,fr*0x3f );
  632.       FM_KeyOn(j);
  633.     }
  634.     msdelay(5);
  635.     if(kbhit()) i = 1000;
  636.   }
  637.  
  638.   if(!kbhit()) {
  639.     for(i = 0; i < 8; i++) {          // Make sure all the notes are right
  640.       FM_SetFreq(i,endfreq[i]);
  641.       FM_KeyOn(i);
  642.     }
  643.  
  644.     for(i = 0x3f ; i >= 0; i-= 1) {   // quiet down slowly
  645.       for(j = 0; j < 8; j++) {
  646.     FM_SetVol(j,i);
  647.       }
  648.       msdelay(i*2+40);
  649.       if(kbhit() & i) i = 1;
  650.     }
  651.   }
  652.  
  653.   for(i = 0; i < 9; i++) {            // Silence them all
  654.     FM_SetVol(i,0);                   // volume off
  655.     FM_SetVoice(i,inst[0]);           // this instrument has a decay, so it
  656.                       // gets all the way quiet
  657.     FM_SetFreq(i,1);                  // Low freq = quiet
  658.   }
  659.  
  660. }
  661. /**************************************************************************
  662.   void mididemo(void)
  663.  
  664.   DESCRIPTION: Example function that loads and "plays" a  midi file
  665.  
  666. **************************************************************************/
  667. void mididemo(void)
  668. {
  669.   int i,err;
  670.   char errstring[256],r=0;
  671.   char str[80];
  672.   static MIDI *bach  = NULL;
  673.  
  674.   midi_patchmap = mypatchmap;
  675.  
  676.   _clearscreen(_GCLEARSCREEN);                                    // clear screen
  677.  
  678.   FM_Reset();
  679.  
  680.   for(i = 0 ; i < 9; i++) {
  681.     FM_SetVol(i,0);
  682.     FM_SetVoice ( i,inst[0]) ;                 // initialize voice
  683.   }
  684.   if(!bach) {
  685.                           // load a midi file
  686.     err = ReadMidi("cannon_d.mid",&bach,(char *)errstring);
  687.     if(err) {
  688.       printf("MIDI read ERROR: %s\n",errstring);
  689.       printf("Exit?\n");
  690.       r = getch();
  691.       if(r != 'n') return;
  692.     }
  693.     midi_data = bach;
  694.     midi_reset = TRUE;
  695.   }
  696.  
  697.   //printf("FORMAT:  %d  TRACKS: %d   DIVISION: %d\n",
  698.   //        bach->format,bach->num_tracks,bach->divisions);
  699.  
  700.   _settextcolor(5);
  701. //  textcolor(MAGENTA);
  702.   _settextposition(2,30);
  703.   _outtext("MIDI demo menu");
  704.  
  705.   _settextcolor(3);
  706. //  textcolor(CYAN);
  707.   _settextposition(4,30);
  708.   _outtext("V,v - Change music volume");
  709.   _settextposition(5,30);
  710.   _outtext("T,t - Change music tempo");
  711.   _settextposition(6,30);
  712.   _outtext("M   - Toggle music: ");
  713.   _settextcolor(2);
  714.   if(midi_on) _outtext("ON  ");
  715.   else _outtext("OFF ");
  716.   _settextcolor(3);
  717.   _settextposition(7,30);
  718.   _outtext("R   - Reset Music");
  719.   _settextposition(8,30);
  720.   _outtext("F   - Toggle FM output: ");
  721.   _settextcolor(2);
  722.   if(midi_fmout) _outtext("ON  ");
  723.   else _outtext("OFF ");
  724.   _settextcolor(3);
  725.   _settextposition(9,30);
  726.   _outtext("U   - Toggle MPU output: ");
  727.   _settextcolor(2);
  728.   if(midi_mpuout) _outtext("ON  ");
  729.   else _outtext("OFF ");
  730.   _settextcolor(3);
  731.   _settextposition(10,30);
  732.  
  733.   _outtext("P   - Set MPU-401 MIDI port");
  734.  
  735.   _settextposition(13,30);
  736.  
  737.   _outtext("Q   - Quit");
  738.  
  739.   if(!mpu_available && mpu_checked) {
  740.     _settextposition(20,1);
  741.     _outtext("Current MPU-401 midi port is invalid.");
  742.   }
  743.  
  744.  
  745.   while(toupper(r) != 'Q') {                  // MAIN LOOP
  746.     _settextposition(14,30);                            // print temppo and volume stats
  747.     _settextcolor(15);
  748. //    textcolor(WHITE);
  749. //    cprintf("Music Volume: %d  ",music_volume);
  750.     _outtext("Music Volume:  ");
  751.     print_num(music_volume);
  752.  
  753.     _settextposition(15,30);
  754.     sprintf(str,"Music Tempo:  %.2f  ",midi_usertempo);
  755.     _outtext(str);
  756.  
  757. //    print_num(midi_usertempo);
  758.  
  759.     while(!kbhit()) {                         // handle the keyboard
  760.       if(mpu_checked) {
  761.     _settextposition(4,1);                          // check midi status while we wait
  762.     if(mpu_timeout < 1000) _outtext("MPU status: OK!         ");
  763.     else _outtext("MPU status: Timing out  ");
  764.     _settextposition(5,1);
  765.     printf("Current port: %X  ",midi_port);
  766.       }
  767.     }
  768.     r = getch();                              // get keystroke
  769.  
  770.     if(r == 'V') {                            // Handle keystrokes
  771.       music_volume++;
  772.       if(music_volume > 0x3f) music_volume = 0x3f;
  773.     }
  774.     else if(r == 'v') {
  775.       if(music_volume > 0) music_volume--;
  776.     }
  777.     else if(toupper(r) == 'R') {
  778.       midi_reset = TRUE;
  779.     }
  780.     else if(r == 'T') {
  781.       midi_usertempo *= 1.02;
  782.       if(midi_usertempo > 10.0) midi_usertempo = 10.0;
  783.     }
  784.     else if(r == 't') {
  785.       midi_usertempo *= 0.98;
  786.       if(midi_usertempo < 0.1) midi_usertempo = 0.1;
  787.     }
  788.     else if(toupper(r) == 'M') {
  789.       midi_on ^= TRUE;
  790.       _settextposition(6,50);
  791.       _settextcolor(2);
  792.       if(midi_on) _outtext("ON  ");
  793.       else _outtext("OFF ");
  794.       _settextcolor(3);
  795.     }
  796.     else if(toupper(r) == 'P') {               // Get a new MPU port address
  797.       _settextposition(1,19);
  798.       printf("Enter new port address in hex values [%x]: ",midi_port);
  799.       gets(errstring);
  800.       if(strlen(errstring)) sscanf(errstring,"%x",&midi_port);
  801.  
  802.                            // check for accidents
  803.       if(midi_port < 0x200 || midi_port > 0x360) midi_port = 0x330;
  804.       mpu_available  = MPU_Reset();
  805.       _settextposition(20,1);
  806.       if(!mpu_available) _outtext("Current MPU-401 midi port is invalid.");
  807.       else printf("                                               ");
  808.       _settextposition(19,1);
  809.       _outtext("                                                    ");
  810.       mpu_checked = TRUE;
  811.     }
  812.     else if(toupper(r) == 'F') {               // Toggle output
  813.       midi_fmout ^= TRUE;
  814.       _settextcolor(3);
  815. //      textcolor(CYAN);
  816.       _settextposition(8,54);
  817.       _settextcolor(2);
  818.       if(midi_fmout) _outtext("ON  ");
  819.       else _outtext("OFF ");
  820.       _settextcolor(3);
  821.     }
  822.     else if(toupper(r) == 'U' && mpu_available) { // Toggle output
  823.       midi_mpuout ^= TRUE;
  824.       _settextcolor(3);
  825. //      textcolor(CYAN);
  826.       _settextposition(9,55);
  827.       _settextcolor(2);
  828.       if(midi_mpuout) _outtext("ON  ");
  829.       else _outtext("OFF ");
  830.       _settextcolor(3);
  831.     }
  832.   }
  833. }
  834.  
  835.  
  836. /**************************************************************************
  837.   void bitprint(char byte)
  838.  
  839.   DESCRIPTION:  Prints individual bits and then a HEX value
  840.  
  841. **************************************************************************/
  842. void bitprint(unsigned char byte)
  843. {
  844.   int i;
  845.   char str[90];
  846.   _outtext("  ");
  847. //  cprintf("  ");
  848.                     // go through bits
  849.   for(i = 7; i >= 0; i--) {
  850.     if(getbit(byte,i)) {            // 1's are yellow
  851.       _settextcolor(14);
  852. //      textcolor(YELLOW);
  853.       _outtext("1");
  854.     }
  855.     else {                          // 0's are dark grey
  856.       _settextcolor(8);
  857. //      textcolor(DARKGRAY);
  858.      _outtext("0");
  859. //      cprintf("0");
  860.     }
  861.   }
  862.   _settextcolor(9);
  863. //  textcolor(LIGHTBLUE);             // print the hex value
  864.   sprintf(str,"  %c%c",hexchar[byte/16],hexchar[byte%16]);
  865.  
  866.   _outtext(str);
  867.   _settextcolor(7);
  868. //  textcolor(WHITE);
  869. }
  870.  
  871.  
  872.  
  873. /**************************************************************************
  874.   void fmdemo()
  875.  
  876.   DESCRIPTION:  Allows th user to mess around with instruments and
  877.         play a few notes.
  878.  
  879.  
  880. **************************************************************************/
  881. void fmdemo(void)
  882. {
  883.   unsigned int i,cx,cy,voice=0,instrument = 0;
  884.   int drawvoice = 1,rythm = 0;
  885.   char r = 0;
  886.  
  887.   _clearscreen(_GCLEARSCREEN);                          // clear screen
  888.   _settextposition(1,1);
  889.   _outtext("FM demonstration screen");
  890. //  printf("FM demonstration screen");
  891.   FM_Reset();
  892.   for(i = 0; i < 9; i++) FM_KeyOff(i);
  893.  
  894.   _settextposition(16,1);
  895.   _outtext("IJKL = cursor movement\r\n");
  896.   _outtext("<space> = toggle bit\r\n");
  897.   _outtext("numbers = play notes\r\n");
  898.   _outtext("v = change voice\r\n");
  899.   _outtext("n = Change instrument\r\n");
  900.   _outtext("r = toggle rythm mode\r\n");
  901.   _outtext("q = quit");
  902.  
  903.   _settextcursor(0x0007);
  904.  
  905.   for( i = 0; i < 8; i++) {          // initialize voices
  906.     FM_SetVoice ( i,inst[instrument]) ;
  907.     FM_SetVol(i,0);
  908.   }
  909.  
  910.   cx = 54;cy = 5;                    // init cursor position
  911.  
  912.   for(i = 0; i < 11; i++) {          // print register names
  913.     _settextposition(i+5,50-strlen(regname[i]));
  914.     _settextcolor(5);
  915. //    textcolor(MAGENTA);
  916. //    cprintf("%s",regname[i]);
  917.     _outtext(regname[i]);
  918.   }
  919.  
  920.  
  921.   while(r != 'Q') {                  // main input loop
  922.     if(drawvoice) {
  923.       for(i = 0; i < 11; i++) {      // display instrument data
  924.     _settextposition(i+5,52);
  925.     bitprint(inst[instrument][i]);
  926.       }
  927.       for(i = 0; i < 9; i++) {
  928.     FM_SetVoice ( i,inst[instrument]) ; // initialize new voice
  929.       }
  930.       drawvoice = 0;
  931.       _settextcolor(8);
  932. //      textcolor(LIGHTGRAY);
  933.       _settextposition(4,52);
  934.       _outtext("Instrument #");
  935. //      _outtext(ecvt(instrument));
  936. //      cprintf("Instrument #%d ",instrument);
  937.       print_num(instrument);
  938.     }
  939.  
  940.     _settextposition(cy,cx);                   // put cursor in right spot
  941.  
  942.     while(!kbhit()){
  943.     }
  944.  
  945.     r = toupper(getch());
  946.     if(r >= '0' && r <= '9') {
  947.       FM_KeyOff(voice);
  948.       FM_SetVoice(voice,inst[instrument]);
  949.       FM_SetNote ( voice, (r-'0'+3) * 8) ;
  950.       FM_SetVol(voice,music_volume);
  951.       FM_KeyOn(voice);
  952.     }
  953.     else if(r == 'I') {              // i,j,k,l = cursor movement
  954.       cy = cy -1;
  955.       if(cy<5) cy = 5;
  956.     }
  957.     else if(r == 'K') {
  958.       cy = cy +1;
  959.       if(cy >15) cy = 15;
  960.     }
  961.     else if(r == 'J') {
  962.       cx = cx -1;
  963.       if(cx<54) cx = 54;
  964.     }
  965.     else if(r == 'L') {
  966.       cx = cx +1;
  967.       if(cx>61) cx = 61;
  968.     }
  969.     else if(r == ' ') {              // space = toggle bit
  970.       togbit(inst[instrument][cy-5],(7-(cx-54)));
  971.       drawvoice = 1;
  972.     }
  973.     else if(r == 'N') {               // I = change instrument
  974.       instrument++;
  975.       if(instrument > 8) instrument = 0;
  976.       drawvoice = 1;
  977.     }
  978.     else if(r == 'R') {              // r = toggle rythm mode
  979.       if(rythm) rythm = 0;
  980.       else rythm = 1;
  981.       FM_RythmMode(rythm);           // do it
  982.       FM_RythmOn(FM_HIHAT);
  983.       _settextposition(2,1);                   // tell the user
  984.       if(rythm) _outtext("Rythm Mode ON  (voices 6,7,8 only) ");
  985.       else       _outtext("Rythm Mode OFF                     ");
  986.     }
  987.     else if(r == 'V') {              //  v = change voice
  988.       FM_KeyOff(voice);
  989.       FM_SetVol(voice,0);
  990.       voice ++;
  991.       if(voice > 8) voice = 0;
  992.       _settextposition(1,3);
  993.       cprintf("Voice: %d ",voice);
  994.     }
  995.     else if(r == 'W') {              // Frequency ramp
  996.       for(i = 0; i < 0xf000; i+= 0x10) {
  997.     FM_SetFreq(voice,i);
  998.     FM_KeyOn(voice);
  999.     msdelay(5);
  1000.       }
  1001.     }
  1002.  
  1003.  
  1004.   }
  1005.   for(i = 0; i < 9; i++) {
  1006.     FM_SetVol(i,0);
  1007.   }
  1008.  
  1009. }
  1010.  
  1011.  
  1012.  
  1013. /**************************************************************************
  1014.   void introtext(void)
  1015.  
  1016.   DESCRIPTION: Display introduction text for the user.
  1017.  
  1018.  
  1019. **************************************************************************/
  1020. void introtext(void)
  1021. {
  1022.   _clearscreen(_GCLEARSCREEN);
  1023.    _settextposition(1,1);
  1024.   _outtext("Varmint's Audio Tools for Watcom (Version: 0.51) Demonstration\n");
  1025.  
  1026. //  ,VAT_VERSION);
  1027. //  printf("\n");
  1028.   _settextcolor(14);
  1029. //  textcolor(YELLOW);
  1030.   _settextposition(3,1);
  1031.   _outtext("Please edit the file survey.txt and return it to:\r\n");
  1032.   _outtext("\n");
  1033.   _outtext("     gavinb@ix.netcom.com\n");
  1034.   _outtext("\n");
  1035.   _outtext("This is the first version of Varmit Audio Tools to be\n");
  1036.   _outtext("ported to Watcom Cv9.5.  Use it with extreme caution\n");
  1037.   _outtext("and don't leave any food out for the rats.\n");
  1038.  
  1039.   _settextcolor(15);
  1040.   _outtext("\n\n");
  1041.   _outtext("To compile you must use the /zu command line option\n");
  1042.   _outtext("wcl386 /zu sound.c myprog.c\n");
  1043.   _outtext("\n\n");
  1044.  
  1045.   _settextcolor(14);
  1046.   _outtext("If you have not seen the real mode version of this program\n");
  1047.   _outtext("I recommend you check that version out.\n");
  1048.  
  1049.   _outtext("\n");
  1050.   _outtext("\n\n                      -Brian Gavin\n");
  1051.  
  1052.   _outtext("\n\nPlease press the space bar to continue...");
  1053.  
  1054.   while(!kbhit());
  1055.   getch();
  1056. }
  1057.  
  1058.  
  1059. /**************************************************************************
  1060.   void diagnostics(void)
  1061.  
  1062.   DESCRIPTION:  This prepares survey.txt to receive diagnostic information
  1063.         and writes a few introductory things in that file.
  1064.  
  1065. **************************************************************************/
  1066. void diagnostics(void)
  1067. {
  1068.   char *e;
  1069.   int i,j,k;
  1070.   DWORD t;
  1071.  
  1072.   diagoutput = fopen("survey.txt","w");    // Open survey file
  1073.   if(!diagoutput) return;
  1074.  
  1075.   _outtext("\nTesting and recording system configuration.\n");
  1076.                        // Write the survey
  1077.   fprintf(diagoutput,"Survey for Varmint's Audio tools.\n");
  1078.   fprintf(diagoutput,"\n");
  1079.   fprintf(diagoutput,"Watcom Cv9.5 port \n");
  1080.   fprintf(diagoutput,"Please email the completed survey to gavinb@ix.netcom.com\n");
  1081.   fprintf(diagoutput,"-----------------------------------------------------------------------------\n");
  1082.   fprintf(diagoutput,"VERSION %s (beta)\n",VAT_VERSION);
  1083.   fprintf(diagoutput,"\n");
  1084.   fprintf(diagoutput,"1) What's your name and email address?\n");
  1085.   fprintf(diagoutput,"\n");
  1086.   fprintf(diagoutput,"\n");
  1087.   fprintf(diagoutput,"2) How did you hear about Varmint's Audio tools and where did you find\n");
  1088.   fprintf(diagoutput,"   this copy?\n");
  1089.   fprintf(diagoutput,"\n");
  1090.   fprintf(diagoutput,"\n");
  1091.   fprintf(diagoutput,"3) Did the demo work on your computer?  If not, please describe what happened.\n");
  1092.   fprintf(diagoutput,"\n");
  1093.   fprintf(diagoutput,"\n");
  1094.   fprintf(diagoutput,"4) Have you tried earlier versions of VAT?  What versions?  Did the demos work?\n");
  1095.   fprintf(diagoutput,"\n");
  1096.   fprintf(diagoutput,"\n");
  1097.   fprintf(diagoutput,"5) Have you been able to use VAT in your own programs?  What features made\n");
  1098.   fprintf(diagoutput,"   it easy or difficult to do so?\n");
  1099.   fprintf(diagoutput,"\n");
  1100.   fprintf(diagoutput,"\n");
  1101.   fprintf(diagoutput,"6) Please describe your computer system:\n");
  1102.   fprintf(diagoutput,"\n");
  1103.   fprintf(diagoutput,"                CPU (eg: 386,486,Pentium):\n");
  1104.   fprintf(diagoutput,"\n");
  1105.   fprintf(diagoutput,"          Internal clock speed (eg:66Mhz):\n");
  1106.   fprintf(diagoutput,"\n");
  1107.   fprintf(diagoutput,"  Operating system(eg: DOS/Windows, OS/2):\n");
  1108.   fprintf(diagoutput,"\n");
  1109.   fprintf(diagoutput,"        Sound card (eg: PAS16, GUS, SB16):\n");
  1110.   fprintf(diagoutput,"\n");
  1111.   fprintf(diagoutput,"\n");
  1112.   fprintf(diagoutput,"7) Please add any additional praise or chastisement of Varmint's Audio Tools:\n");
  1113.  
  1114.                         // Print some autodiag info
  1115.   fprintf(diagoutput,"\n---------- AUTO DIAGNOSTIC INFORMATION ---------\n");
  1116.   fprintf(diagoutput,"Everything below here was written automatically by\n");
  1117.   fprintf(diagoutput,"the VAT demo.  Please do not delete these lines.\n");
  1118.   fprintf(diagoutput,"-------------------------------------------------\n\n");
  1119.  
  1120.   e = getenv("BLASTER");                    // Record BLASTER variable
  1121.   if(e) fprintf(diagoutput,"BLASTER env variable: %s\n",e);
  1122.  
  1123.   t = clock();                              // measure system performance
  1124.   for(i = 0; i < 1000; i++) {
  1125.     for(j = 0; j <  1000; j++ ) {
  1126.       k = i * j;
  1127.     }
  1128.   }
  1129.   t = clock()-t;
  1130.  
  1131.   fprintf(diagoutput,"Integer speed rating: %lu\n",t);
  1132.  
  1133.                         // Check available memory
  1134. //  fprintf(diagoutput,"Core left: %lu\n",farcoreleft());
  1135.   fflush(diagoutput);
  1136. }
  1137.  
  1138.  
  1139. /**************************************************************************
  1140.   void debugoptions(void)
  1141.  
  1142.   DESCRIPTION: Allows the user to set certain debug options.  These debug
  1143.            options will eventually be removed from the code when it
  1144.            is debugged.
  1145.  
  1146. **************************************************************************/
  1147. void debugoptions(void)
  1148. {
  1149.   char r = 0;
  1150.  
  1151.  
  1152.   _clearscreen(_GCLEARSCREEN);
  1153.   printf("VAT debug options\n");
  1154.  
  1155.   _settextcolor(9);
  1156.   //textcolor(LIGHTBLUE);
  1157.  
  1158.   _settextposition(10,5);
  1159.   cprintf("1) Set Anitistatic byte");
  1160.   _settextposition(5,5);
  1161.   if(debug_antistatic) printf("ON");
  1162.   else printf("OFF");
  1163.  
  1164.   _settextposition(10,6);
  1165.   cprintf("2) Disable interrupts in mixing Kernel");
  1166.   _settextposition(5,6);
  1167.   if(debug_intdisable) printf("ON");
  1168.   else printf("OFF");
  1169.  
  1170.   _settextposition(5,20);
  1171.   printf("Press a number to toggle an option, or <space> to continue.");
  1172.  
  1173.   while(r != ' ') {
  1174.     r = toupper(getch());
  1175.     if(r == '1') {
  1176.       debug_antistatic ^= TRUE;
  1177.       _settextposition(5,5);
  1178.       if(debug_antistatic) printf("ON  ");
  1179.       else printf("OFF ");
  1180.     }
  1181.     else if(r == '2') {
  1182.       debug_intdisable ^= TRUE;
  1183.       _settextposition(5,6);
  1184.       if(debug_intdisable) printf("ON  ");
  1185.       else printf("OFF ");
  1186.     }
  1187.   }
  1188.  
  1189. }
  1190.  
  1191.  
  1192.  
  1193.